const Path = require('path');
const Cp = require('child_process');
const Webpack = require('webpack');

const getGitRevision = () => {
  return {
    version: Cp.execSync('git describe --tags --always', { encoding: 'utf8' }),
    commit: Cp.execSync('git rev-list --max-count=1 --no-merges HEAD', {
      encoding: 'utf8',
    }),
    branch: Cp.execSync('git rev-parse --abbrev-ref HEAD', { encoding: 'utf8' }),
  };
};
const resolve = dir => {
  return Path.join(__dirname, './', dir);
};

module.exports = {
  lintOnSave: process.env.NODE_ENV === 'development',
  productionSourceMap: false,
  devServer: {
    port: 5333,
    disableHostCheck: true,
    overlay: {
      warnings: true,
      errors: true,
    },
  },
  css: {
    loaderOptions: {
      less: {
        lessOptions: {
          javascriptEnabled: true,
          modifyVars: {
            hack: `true; @import (reference) "${resolve('src/assets/styles/vant.less')}";`,
          },
        },
      },
      sass: {
        additionalData: `@import "./src/assets/styles/basic/mixins.scss"; @import "./src/assets/styles/basic/variables.scss";`,
      },
    },
  },
  chainWebpack(config) {
    config.plugins.delete('preload');
    config.plugins.delete('prefetch');
    config.resolve.alias.set('@', resolve('src'));
    config.performance.set('hints', false);
    config.module
      .rule('images')
      .use('url-loader')
      .loader('url-loader')
      .tap(options => Object.assign(options, { limit: 10240 }));
    config.plugin('DefinePlugin').use(
      new Webpack.DefinePlugin({
        __VERSION__: JSON.stringify(getGitRevision().version.trim()),
        __COMMIT__: JSON.stringify(getGitRevision().commit.trim()),
        __BRANCH__: JSON.stringify(getGitRevision().branch.trim()),
        __BUILD_DATE__: JSON.stringify(new Date()),
        __VUE_I18N_FULL_INSTALL__: false,
        __VUE_I18N_LEGACY_API__: false,
        __INTLIFY_PROD_DEVTOOLS__: false,
      }),
    );
    config.when(process.env.NODE_ENV === 'development', () => {
      config.merge({ devtool: 'cheap-source-map' });
    });
    config.when(process.env.NODE_ENV === 'production', () => {
      config.optimization.minimizer('terser').use(require.resolve('terser-webpack-plugin'), [
        {
          parallel: true,
          test: /\.js(\?.*)?$/i,
          sourceMap: false,
          terserOptions: {
            compress: {
              drop_debugger: true,
              pure_funcs: ['console.log'],
            },
            warnings: false,
            output: {
              keep_quoted_props: true,
            },
          },
        },
      ]);
      config.optimization.minimizer('css').use(require.resolve('css-minimizer-webpack-plugin'), [
        {
          minify: async (data, inputMap) => {
            const CleanCSS = require('clean-css');
            const [[filename, input]] = Object.entries(data);
            const minifiedCss = await new CleanCSS({ sourceMap: true }).minify({
              [filename]: {
                styles: input,
                sourceMap: inputMap,
              },
            });

            return {
              css: minifiedCss.styles,
              map: minifiedCss.sourceMap.toJSON(),
              warnings: minifiedCss.warnings,
            };
          },
        },
      ]);
      config.optimization.splitChunks({
        chunks: 'all',
        minSize: 20000,
        minChunks: 2,
        maxAsyncRequests: 5,
        maxInitialRequests: 3,
        automaticNameDelimiter: '-',
        cacheGroups: {
          libs: {
            chunks: 'initial',
            test: /[\\/]node_modules[\\/]/,
            name: 'chunk-libs',
            priority: 10,
            enforce: true,
            reuseExistingChunk: true,
          },
          commons: {
            test: /common\/|components\/|utils\//,
            name: 'chunk-commons',
            chunks: 'initial',
            minChunks: 3,
            priority: 5,
            enforce: true,
            reuseExistingChunk: true,
          },
          vantUI: {
            test: /[\\/]node_modules[\\/]_?vant(.*)/,
            name: 'chunk-vant',
            priority: 20,
            enforce: true,
            chunks: 'all',
            reuseExistingChunk: true,
          },
        },
      });
      config.optimization.runtimeChunk({
        name: entrypoint => `runtime-${entrypoint.name}`,
      });
    });
  },
  publicPath: process.env.NODE_ENV === 'production' ? './' : '/',
};
